package com.nhutcm.trackingthief.service;

import java.util.List;
import java.util.Locale;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

import com.nhutcm.trackingthief.network.TrackingThiefNetwork;
import com.nhutcm.trackingthief.receiver.TrackingThiefReceiver;
import com.nhutcm.trackingthief.utils.Constant;

public class GPSService extends Service implements LocationListener {

	public static final String TAG = "com.nhutcm.trackingthief.utils.GPSService";
	private final Context mContext;
	boolean isGPSEnabled = false;
	boolean isNetworkEnabled = false;
	boolean canGetLocation = false;

	Location location;

	private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
	private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute

	protected LocationManager locationManager;

	public GPSService(Context context) {
		this.mContext = context;
		getCurLocation();
	}

	public synchronized Location getCurLocation() {
		try {
			locationManager = (LocationManager) mContext
					.getSystemService(LOCATION_SERVICE);

			isGPSEnabled = locationManager
					.isProviderEnabled(LocationManager.GPS_PROVIDER);

			isNetworkEnabled = locationManager
					.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

			if (!isGPSEnabled && !isNetworkEnabled) {
			} else {
				this.canGetLocation = true;
				if (isGPSEnabled) {
					locationManager.requestLocationUpdates(
							LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES,
							MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
					Log.d(TAG, "GPS is enable");
					if (locationManager != null) {
						location = locationManager
								.getLastKnownLocation(LocationManager.GPS_PROVIDER);
					}
				}

				if (isNetworkEnabled) {
					if (location == null) {
						locationManager.requestLocationUpdates(
								LocationManager.NETWORK_PROVIDER,
								MIN_TIME_BW_UPDATES,
								MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
						Log.d(TAG, "Network is enable");
						if (locationManager != null) {
							location = locationManager
									.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
						}
					}

				}

			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return location;
	}

	/**
	 * Stop using GPS listener Calling this function will stop using GPS in your
	 * app
	 * */
	public void stopUsingGPS() {
		if (locationManager != null) {
			locationManager.removeUpdates(GPSService.this);
		}
	}

	/**
	 * Function get location
	 */
	public Location getLocation() {
		return location;
	}

	public boolean canGetLocation() {
		return this.canGetLocation;
	}

	public void getAddressAndSendToEmail() {
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD
				&& Geocoder.isPresent()) {
			if (location != null) {
				(new GetAddressTask(mContext)).execute(location);
			}
		}
	}

	@Override
	public void onLocationChanged(Location l) {
		if (location != null) {
			this.location = l;
			getAddressAndSendToEmail();
		}
	}

	@Override
	public void onProviderDisabled(String provider) {
	}

	@Override
	public void onProviderEnabled(String provider) {
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
	}

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	private class GetAddressTask extends AsyncTask<Location, Void, String> {

		public static final String TAG = "GetAddressTask";
		Context mContext;

		public GetAddressTask(Context context) {
			super();
			mContext = context;
		}

		@Override
		protected String doInBackground(Location... params) {
			Location location = params[0];
			if (location != null) {
				Log.i(TAG,
						location.getLatitude() + "," + location.getLongitude());
			}
			String addressText = "";
			Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());
			try {
				List<Address> addresses = geocoder.getFromLocation(
						location.getLatitude(), location.getLongitude(), 1);

				if (addresses != null && addresses.size() > 0) {
					Address address = addresses.get(0);

					String streetName = address.getAddressLine(0);
					if (streetName == null) {
						streetName = address.getFeatureName();
						if (streetName == null) {
							streetName = address.getThoroughfare();
						}
					}

					String district = address.getSubAdminArea();
					if (district == null) {
						district = address.getAddressLine(2);
					}

					String cityName = address.getAdminArea();

					if (cityName == null) {
						cityName = address.getAddressLine(3);
						if (cityName == null) {
							cityName = address.getLocality();
						}
					}

					String countryName = address.getCountryName();

					addressText = String.format("%s, %s, %s, %s", streetName,
							district, cityName, countryName);
					Constant.lastestAddress = addressText;

					Log.d(TAG, addressText);
				} else {
					Log.w(TAG, "No address found");
				}

			} catch (Exception ex) {
				Log.e(TAG, ex.getMessage());
			}
			return addressText;
		}

		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			if (result.equals("")) {
				result = Constant.lastestAddress;
			} else {
				stopUsingGPS();
			}

			Intent intent = new Intent(mContext, TrackingThiefNetwork.class);
			intent.putExtra(TrackingThiefReceiver.FILE_PATH, result);
			mContext.startService(intent);

		}

	}

}
